// ****************************************************************************
//               Copyright (C) Microsoft Corporation.
// @File: SmartPtrTests.cpp
//
// PURPOSE: Classes related to the unit test of CSmartPtr.
// AUTHOR:  ZJ Ai
//
// NOTES: 
//     
// HISTORY:
//   ------ ZJ Ai  05/06/2012 creating the file
//
// @EndHeader@
// ****************************************************************************
#include "stdafx.h"

#include "tdd.h"
#include "tddassert.h"

#include "..\\SmartPtr\\SmartPtr.h"

#include "MockObject.h"

namespace SmartPtr
{
	namespace UnitTest
	{
		TESTCLASS(CSmartPtrTests)
		{
			TESTMETHOD(TestNewSmartPtrNULL)
			{
				// test new null for basic type
				CSmartPtr<int> pInt = NULL;
				TDD_VERIFY(pInt == NULL);

				// test new null for user-defined type
				CSmartPtr<MockBase> pObj = NULL;
				TDD_VERIFY(pObj == NULL);
			}

			TESTMETHOD(TestNewSmartPtrBasicType)
			{
				// test for int
				CSmartPtr<int> intPtr = new int;
				TDD_VERIFY(intPtr != NULL);

				// test for char
				CSmartPtr<char> charPtr = new char;
				TDD_VERIFY(charPtr != NULL);

				// test for double
				CSmartPtr<double> doublePtr = new double;
				TDD_VERIFY(doublePtr != NULL);
			}

			TESTMETHOD(TestNewSmartUserDefinedClass)
			{
				CSmartPtr<MockBase> mockBasePtr = new MockBase;
				TDD_VERIFY(mockBasePtr != NULL);
			}

			TESTMETHOD(TestAssignOperaor)
			{
				// Test for same class type
				CSmartPtr<MockBase> mockBasePtr = new MockBase;
				TDD_VERIFY(mockBasePtr != NULL);

				CSmartPtr<MockBase> mockBasePtr2 = new MockBase;
				TDD_VERIFY(mockBasePtr2 != NULL);

				CSmartPtr<MockBase> mockBasePtr3 = mockBasePtr;
				TDD_VERIFY(mockBasePtr3 != NULL);
				TDD_VERIFY(strcmp(mockBasePtr3->GetClassName(), mockBasePtr->GetClassName()) == 0);

				mockBasePtr2 = mockBasePtr;
				TDD_VERIFY(strcmp(mockBasePtr2->GetClassName(), mockBasePtr->GetClassName()) == 0);
				
				// Test for Base and derive class type 
				CSmartPtr<MockBase> mockBasePtr4 = new MockDerive;
				TDD_VERIFY(mockBasePtr4 != NULL);
				TDD_VERIFY(mockBasePtr4->VirtualTest() == 2);

				// the following should be compile error
				//CSmartPtr<MockDerive> mockDerivePtr = new MockBase;

				// dynamic_cast from derive ptr to base ptr
				CSmartPtr<MockDerive> mockDerivePtr2 = ptr_dynamic_cast<MockDerive>(mockBasePtr4);
				TDD_VERIFY(mockDerivePtr2 != NULL);

				// dynamic_cast from base ptr to derive ptr
				CSmartPtr<MockDerive> mockDerivePtr3 = new MockDerive;
				mockBasePtr4 = ptr_dynamic_cast<MockBase>(mockDerivePtr3);
				TDD_VERIFY(mockBasePtr4 != NULL);		
				
				// ATTENTION the following code will be compiled error!!
				//mockDerivePtr4 = mockBasePtr5;
				
				CSmartPtr<MockBase> mockBasePtr6 = new MockBase;
				CSmartPtr<MockDerive> mockDerivePtr5 = new MockDerive;
				mockDerivePtr5 = ptr_dynamic_cast<MockDerive>(mockBasePtr6);
				TDD_VERIFY(mockDerivePtr5 == NULL);
			}

			//TESTMETHOD(TestRefCount)
			//{
			//	// test for null
			//	{
			//		CSmartPtr<int> mockInt = NULL;
			//		TDD_VERIFY(mockInt == NULL);
			//		// the ref count for the NULL is 0
			//		TDD_VERIFY(mockInt.GetRefCount() == 0);
			//	}

			//	{
			//		CSmartPtr<MockBase> mockObj = NULL;
			//		TDD_VERIFY(mockObj == NULL);
			//		TDD_VERIFY(mockObj.GetRefCount() == 0);
			//	}


			//	// test for basic type
			//	{
			//		CSmartPtr<int> mockInt = new int(1);
			//		TDD_VERIFY(mockInt != NULL);
			//		TDD_VERIFY(*mockInt == 1);
			//		TDD_VERIFY(mockInt.GetRefCount() == 1);
			//	}
			//	
			//	CSmartPtr<int> mockObj = new int(2);
			//	{
			//		CSmartPtr<int> mockInt2 = mockObj;
			//		TDD_VERIFY(mockObj.GetRefCount() == mockInt2.GetRefCount() 
			//			&& mockInt2.GetRefCount() == 2);
			//	}
			//	
			//	// test for user-defined type
			//	{
			//		CSmartPtr<MockBase> mockObj = new MockBase();
			//		TDD_VERIFY(mockObj != NULL);
			//		TDD_VERIFY(mockObj.GetRefCount() == 1);
			//	}

			//	CSmartPtr<MockBase> mockObj1 = new MockBase();
			//	{
			//		CSmartPtr<MockBase> mockObj2 = mockObj1;
			//		TDD_VERIFY(mockObj1.GetRefCount() == mockObj2.GetRefCount() 
			//			&& mockObj2.GetRefCount() == 2);
			//	}
			//	TDD_VERIFY(mockObj1.GetRefCount() == 1);

			//	// test for T* assignment
			//	MockBase* pTemp = new MockBase();
			//	CSmartPtr<MockBase> mockObj2 = pTemp;
			//	{
			//		CSmartPtr<MockBase> mockObj3 = pTemp;
			//		TDD_VERIFY(mockObj2.GetRefCount() == mockObj3.GetRefCount() 
			//			&& mockObj3.GetRefCount() == 2);
			//	}
			//	TDD_VERIFY(mockObj2.GetRefCount() == 1);
			//}

		private:

		};
	}
}